home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / Papers / From CodeWarrior to Delphi / PortableMemory.p < prev    next >
Encoding:
Text File  |  1998-06-17  |  6.5 KB  |  347 lines  |  [TEXT/CWIE]

  1. UNIT PortableMemory;
  2.  
  3. INTERFACE
  4.  
  5. {$IFC UNDEFINED INTEL}
  6. {$SETC INTEL=FALSE}
  7. {$ENDC}
  8.  
  9. {$IFC INTEL}
  10. USES
  11.     Settings;
  12. {$ELSEC}
  13. USES
  14.     Settings, Memory;
  15. {$ENDC}
  16.  
  17. TYPE
  18. {$IFC WINTARGET}
  19.     Chunk = LPVOID;
  20. {$ENDC}
  21. {$IFC MACTARGET}
  22.     Chunk = Handle;
  23. {$ENDC}
  24.  
  25. PROCEDURE MoveBytes (source: Ptr; dest: Ptr; nb: longint);
  26.  
  27. FUNCTION MakeChunk (siz: longint; VAR c: Chunk): longint;
  28. FUNCTION SetChunkSize (VAR c: Chunk; siz: longint): longint;
  29. FUNCTION GetChunkSize (VAR c: Chunk): longint;
  30. FUNCTION SetChunkEntry (VAR c: Chunk; recSiz: longint; pEntry: ptr; entrynum: longint): longint;
  31. FUNCTION GetChunkEntry (VAR c: Chunk; recSiz: longint; pEntry: ptr; entrynum: longint): longint;
  32. FUNCTION ZapChunk (VAR c: Chunk): longint;
  33. PROCEDURE LockChunk (c: Chunk);
  34. PROCEDURE UnlockChunk (c: Chunk);
  35. FUNCTION DuplicateChunk (c: Chunk; VAR newchunk: Chunk): longint;
  36. FUNCTION AppendChunk (cFrom: Chunk; VAR cTo: Chunk; sizFrom, sizTo: longint): longint;
  37.  
  38.  
  39. IMPLEMENTATION
  40.  
  41.  
  42. CONST
  43.     mNoErr = 0;
  44.     mChunkIsNil = 15900;
  45.     mHeapAllocErr = 15901;
  46.     mHeapReAllocErr = 15902;
  47.     mIndexTooLow = 15912;
  48.     mIndexTooHigh = 15913;
  49.  
  50. {===================================================================}
  51.  
  52. PROCEDURE MoveBytes (source: Ptr; dest: Ptr; nb: longint);
  53. {$IFC WINTARGET}
  54.     TYPE
  55.         buffer = PACKED ARRAY[1..30000] OF char;
  56.         BufPtr = ^buffer;
  57.     VAR
  58.         ix: integer;
  59.     BEGIN
  60.         FOR ix := 1 TO nb DO
  61.             BufPtr(dest)^[ix] := BufPtr(source)^[ix];
  62.  
  63.         { should use CopyMemory(dest, source, nb); but it has problems}
  64.     END;
  65. {$ENDC}
  66. {$IFC MACTARGET}
  67. BEGIN
  68.     BlockMove(source, dest, nb);
  69. END;
  70. {$ENDC}
  71.  
  72. {--------------------------------------------------------------------------------}
  73.  
  74. {$IFC WINTARGET}
  75.  
  76. FUNCTION MakeChunk (siz: longint; VAR c: Chunk): longint;
  77. VAR
  78.     err: longint;
  79. BEGIN
  80.     c := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, siz);
  81.  
  82.     IF c = NIL THEN
  83.         BEGIN
  84.             err := GetLastError;
  85.             IF err = 0 THEN
  86.                 err := mHeapAllocErr;
  87.         END
  88.     ELSE
  89.         BEGIN
  90.             err := mNoErr;
  91. {I'm not sure that ZeroMemory works yet --}
  92. {$IFC FALSE}
  93.     {$pragmac noreturn on}
  94.             ZeroMemory(c, siz);
  95.     {$pragmac noreturn reset}
  96. {$ENDC}
  97.         END;
  98.     MakeChunk := err;
  99. END;
  100.  
  101.  
  102. {$IFC FALSE}
  103. {Example from Nadine:}
  104. {            program test;}
  105. {            uses}
  106. {                 windows;}
  107. {            var}
  108. {                 dest, src :^unsignedbyte;}
  109. {            begin}
  110. {            {$pragmac noreturn on}
  111. ZeroMemory(dest, sizeof(dest));
  112. FillMemory(dest, sizeof(dest), 1);
  113. CopyMemory(dest, src, sizeof(dest));
  114. MoveMemory(dest, src, sizeof(dest));
  115.             {$pragmac noreturn reset}
  116. {$ENDC}
  117.  
  118.  
  119. FUNCTION SetChunkSize (VAR c: Chunk; siz: longint): longint;
  120. VAR
  121.     newc: Chunk;
  122.     err: longint;
  123. BEGIN
  124.     IF c = NIL THEN
  125.         err := mChunkIsNil
  126.     ELSE
  127.         BEGIN
  128.             newc := HeapReAlloc(GetProcessHeap, 0, c, siz);
  129.             IF newc = NIL THEN
  130.                 BEGIN
  131.                     err := GetLastError;
  132.                     IF err = 0 THEN
  133.                         err := mHeapReAllocErr;
  134.                 END
  135.             ELSE
  136.                 BEGIN
  137.                     err := mNoErr;
  138.                     c := newc;
  139.                 END;
  140.         END;
  141.     SetChunkSize := err;
  142. END;
  143.  
  144.  
  145. FUNCTION GetChunkSize (VAR c: Chunk): longint;
  146. BEGIN
  147.     IF c = NIL THEN
  148.         GetChunkSize := 0
  149.     ELSE
  150.         GetChunkSize := HeapSize(GetProcessHeap, 0, c);
  151. END;
  152.  
  153.  
  154. FUNCTION ZapChunk (VAR c: Chunk): longint;
  155. VAR
  156.     b: BOOL;
  157. BEGIN
  158.     b := HeapFree(GetProcessHeap, 0, c);
  159.     IF b <> 0 THEN
  160.         ZapChunk := mNoErr
  161.     ELSE
  162.         ZapChunk := GetLastError;
  163. END;
  164.  
  165.  
  166. PROCEDURE LockChunk (c: Chunk);
  167. BEGIN
  168. END;
  169.  
  170. PROCEDURE UnlockChunk (c: Chunk);
  171. BEGIN
  172. END;
  173.  
  174. {$ENDC}
  175.  
  176. {--------------------------------------------------------------------------------}
  177.  
  178. {$IFC MACTARGET}
  179.  
  180. FUNCTION MakeChunk (siz: longint; VAR c: Chunk): longint;
  181. BEGIN
  182.     c := NewHandleClear(siz);
  183.     MakeChunk := MemError;
  184. END;
  185.  
  186. FUNCTION SetChunkSize (VAR c: Chunk; siz: longint): longint;
  187. BEGIN
  188.     SetHandleSize(c, siz);
  189.     SetChunkSize := mNoErr;
  190. END;
  191.  
  192.  
  193. FUNCTION GetChunkSize (VAR c: Chunk): longint;
  194. BEGIN
  195.     GetChunkSize := GetHandleSize(c);
  196. END;
  197.  
  198.  
  199. FUNCTION ZapChunk (VAR c: Chunk): longint;
  200. BEGIN
  201.     DisposeHandle(c);
  202.     c := NIL;
  203.     ZapChunk := mNoErr;
  204. END;
  205.  
  206.  
  207. PROCEDURE LockChunk (c: Chunk);
  208. BEGIN
  209.     HLock(c);
  210. END;
  211.  
  212.  
  213. PROCEDURE UnlockChunk (c: Chunk);
  214. BEGIN
  215.     HUnlock(c);
  216. END;
  217.  
  218.  
  219. FUNCTION DuplicateChunk (c: Chunk; VAR newchunk: Chunk): longint;
  220. VAR
  221.     nc: Chunk;
  222. BEGIN
  223.     nc := c;
  224.     DuplicateChunk := HandToHand(nc);
  225.     newchunk := nc;
  226. END;
  227.  
  228.  
  229. FUNCTION AppendChunk (cFrom: Chunk; VAR cTo: Chunk; sizFrom, sizTo: longint): longint;
  230. BEGIN
  231.     AppendChunk := HandAndHand(cFrom, cTo); {append c1 to end of c2}
  232. END;
  233.  
  234. {$ENDC}
  235.  
  236. {--------------------------------------------------------------------------------}
  237.  
  238. {The following routines work for both Mac and Win}
  239.  
  240. FUNCTION CheckChunkSizeForEntryRequested (c: Chunk; recSize, recNum: longint): longint;
  241. VAR
  242.     err, siz, sizNeeded: longint;
  243. BEGIN
  244.     err := 0;
  245.     IF recNum <= 0 THEN
  246.         err := mIndexTooLow
  247.     ELSE
  248.         BEGIN
  249.             siz := GetChunkSize(c);
  250.             sizNeeded := recSize * recNum;
  251.             IF sizNeeded > siz THEN
  252.                 err := mIndexTooHigh;
  253.         END;
  254.     CheckChunkSizeForEntryRequested := err;
  255. END;
  256.  
  257.  
  258. FUNCTION SetChunkEntry (VAR c: Chunk; recSiz: longint; pEntry: ptr; entrynum: longint): longint;
  259. VAR
  260.     err: longint;
  261.     dest: ptr;
  262. BEGIN
  263.     err := CheckChunkSizeForEntryRequested(c, recSiz, entrynum);
  264.     IF err = 0 THEN
  265.         BEGIN
  266. {$IFC MACTARGET}
  267.             dest := PTR(ORD(c^) + (entrynum - 1) * recSiz);
  268. {$ENDC}
  269. {$IFC WINTARGET}
  270.             dest := PTR(ORD(c) + (entrynum - 1) * recSiz);
  271. {$ENDC}
  272.             MoveBytes(pEntry, dest, recSiz);
  273.         END;
  274.  
  275.     SetChunkEntry := err;
  276. END;
  277.  
  278.  
  279. FUNCTION GetChunkEntry (VAR c: Chunk; recSiz: longint; pEntry: ptr; entrynum: longint): longint;
  280. VAR
  281.     err: longint;
  282.     src: ptr;
  283. BEGIN
  284.     err := CheckChunkSizeForEntryRequested(c, recSiz, entrynum);
  285.     IF err = 0 THEN
  286.         BEGIN
  287. {$IFC MACTARGET}
  288.             src := PTR(ORD(c^) + (entrynum - 1) * recSiz);
  289. {$ENDC}
  290. {$IFC WINTARGET}
  291.             src := PTR(ORD(c) + (entrynum - 1) * recSiz);
  292. {$ENDC}
  293.             MoveBytes(src, pEntry, recSiz);
  294.         END;
  295.  
  296.     GetChunkEntry := err;
  297. END;
  298.  
  299.  
  300. FUNCTION DuplicateChunk (c: Chunk; VAR newchunk: Chunk): longint;
  301. VAR
  302.     err, siz: longint;
  303. BEGIN
  304.     siz := GetChunkSize(c);
  305.     newchunk := HeapAlloc(GetProcessHeap, 0, siz);
  306.     IF newchunk = NIL THEN
  307.         BEGIN
  308.             err := GetLastError;
  309.             IF err = 0 THEN
  310.                 err := mHeapAllocErr;
  311.         END
  312.     ELSE
  313.         BEGIN
  314. {$IFC MACTARGET}
  315.             MoveBytes(PTR(c^), PTR(newchunk^), siz);
  316. {$ENDC}
  317. {$IFC WINTARGET}
  318.             MoveBytes(PTR(c), PTR(newchunk), siz);
  319. {$ENDC}
  320.         END;
  321.     DuplicateChunk := err;
  322. END;
  323.  
  324.  
  325. FUNCTION AppendChunk (cFrom: Chunk; VAR cTo: Chunk; sizFrom, sizTo: longint): longint;
  326. VAR
  327.     siz, err: longint;
  328. BEGIN
  329.     siz := sizFrom + sizTo;
  330.     err := SetChunkSize(cTo, siz);    {enlarge c2}
  331.     IF err = 0 THEN
  332.             {append cFrom to end of cTo}
  333.         BEGIN
  334. {$IFC MACTARGET}
  335.             MoveBytes(PTR(cFrom^), PTR(ORD(cTo^) + sizTo), siz);
  336. {$ENDC}
  337. {$IFC WINTARGET}
  338.             MoveBytes(PTR(cFrom), PTR(ORD(cTo) + sizTo), siz);
  339. {$ENDC}
  340.         END;
  341.  
  342.     AppendChunk := err;
  343. END;
  344.  
  345. {--------------------------------------------------------------------------------}
  346.  
  347. END.